import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Routes, Route, Navigate } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';
import AuthProviderContext from './context/AuthProviderContext';
import Header from './views/app/header/Header';
import Sidebar from './views/app/sidebar/Sidebar';
import SettingsPage from './views/settings/SettingsPage';
import AuthProvider from './auth/AuthProvider';
import ConfirmationModalProvider from './components/ConfirmationModalProvider/ConfirmationModalProvider';
import styles from './App.module.scss';

/**
 * Создает новый экземпляр QueryClient.
 * @type { QueryClient } - Экземпляр для управления запросами.
 */
const queryClient: QueryClient = new QueryClient();

/**
 * Отрисовывает главный компонент приложения.
 *
 * @return { React.JSX.Element } Отрисованный компонент приложения.
 */
const App: React.FC = (): React.JSX.Element => {

  /**
   * Открытие/закрытие Sidebar.
   */
  const [isOpenMenu, setToggleMenu] = React.useState(false);

  /**
   * Переключает боковое меню.
   *
   * @return {void} Не возвращает значение.
   */
  const toggleMenu = () => {
    setToggleMenu(!isOpenMenu);
    const settingsPageContainer = document.querySelector('.settingsPage');
    if (!isOpenMenu) {
      settingsPageContainer?.classList.add('toggleWidth');
    } else {
      settingsPageContainer?.classList.remove('toggleWidth');
    }
  };

  return (
    // Обертка для QueryClient
    <QueryClientProvider client={queryClient}>
      { /* Обертка для AuthProvider */}
      <div className={styles.appContainer}>
        <AuthProvider>
          <ConfirmationModalProvider>
            <ToastContainer position="top-right" />
            <Header onMenuToggle={toggleMenu} />
            <div className={styles.sidebarAndContantContainer}>
              <Sidebar isOpenMenu={isOpenMenu} />
              { /* Обертка для контекста AuthProvider */}
              <AuthProviderContext.Consumer>
                { /* Отрисовываем маршруты, доступные пользователю исходя из контекста */}
                {({ availableRoutes }) => {
                  const routesArray = availableRoutes.map((route) => (
                    <Route
                      key={route.path}
                      path={route.path}
                      element={route.route.render()}
                    />
                  ));

                  return (
                    <Routes>
                      {routesArray}
                      <Route index element={<Navigate to={availableRoutes[0]?.path ?? "/"} replace />} />
                      <Route path='/settings' element={<SettingsPage isOpenMenu={isOpenMenu} />} />
                    </Routes>
                  )
                }}
              </AuthProviderContext.Consumer>
            </div>
          </ConfirmationModalProvider>
        </AuthProvider>
      </div>
    </QueryClientProvider>
  );
};

export default App;
